// ==UserScript==
// @name           ahulu
// @namespace      http://www.cs.rochester.edu/u/sadilek
// @description    Augments hulu.com with social networking, imdb, wikipedia, amazon, and rottentomatoes
// @version        0.9
// @include        http://www.hulu.com/*
// ==/UserScript==

/*

This Greasemonkey script adds two panels to hulu.com in which it displays:
+ Brief synopsis of the content 
+ Facebook integration panel
+ Detailed meta-data and information on cast, production, history, etc.
+ Interesting trivia regarding the content
+ Reviews from multiple sources
+ Direct shopping link


Additional information is taken from IMDB, Wikipedia, Amazon, RottenTomatoes, and your social network

*/


function getElementsByClass(searchClass,node,tag) {
    var classElements = new Array();
    if ( node == null )
	node = document;
    if ( tag == null )
	tag = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++) {
	if ( pattern.test(els[i].className) ) {
	    classElements[j] = els[i];
	    j++;
	}
    }
    return classElements[0];
}

function makeIMDBurl(movietitle) {
    return 'http://www.imdb.com/find?q='+ movietitle +';s=tt;site=aka';
}

function findImdbID(url) {
    var m = url.match(/^http:\/\/(.*\.)?imdb.com\/title\/(tt\d*)/i);
    if (m) return m[2];
    return null;
}

function getMovieInfo(url, callback) {
    var url = url;
    GM_xmlhttpRequest({
	method: "GET",
	url: url,
	onreadystatechange: function(details) {
	    callback(extractMovieInfo(details.status, details.readyState, details.responseText, 0));
	}
    });
}

function getWikipediaInfo(url, callback) {
    var url = url;
    GM_xmlhttpRequest({
	method: "GET",
	url: url,
	onreadystatechange: function(details) {
	    callback(extractWikipediaInfo(details.status, details.readyState, details.responseText, 0));
	}
    });
}

function getTriviaInfo(url, callback) {
    var url = url + "trivia";
    GM_xmlhttpRequest({
	method: "GET",
	url: url,
	onreadystatechange: function(details) {
	    callback(extractTriviaInfo(details.status, details.readyState, details.responseText, 0));
	}
    });
}

function getStorylineInfo(url, callback) {
    var url = url;
    GM_xmlhttpRequest({
	method: "GET",
	url: url,
	onreadystatechange: function(details) {
	    callback(extractStorylineInfo(details.status, details.readyState, details.responseText, 0));
	}
    });
}

function extractMovieInfo(status, state, content, index) {
   // document.body.innerHTML =  content.length + " | " + state + " | " +  status + "<br>" + document.body.innerHTML;
    if (state !=4) {
        return;
    }
    var m = content.match(/id="star-bar-user-rate"><b>(\d.\d)<\/b>/);
    if (m == null) {
        return;
    }
    return { rating: m[1], index: index };
}

function extractWikipediaInfo(status, state, content, index) {
    if (state !=4) {
        return;
    }
    var side_idx = content.indexOf("<table class=\"infobox");
    if(side_idx == -1) {
        return;
    }
    var p = content.substring(side_idx, content.length);
    var m = p.substring(0, p.indexOf("</table>")+8);
    if (m == null) {
        return;
    }
    m = m.replace(/href="\/w/g, 'href="http://en.wikipedia.org/w');
    return { rating: m, index: index };
}

function extractTriviaInfo(status, state, content, index) {
    if (state !=4) {
        return;
    }
    var m = [];
    for(i = 0; i < 1; i++) {
        var side_idx = content.indexOf("<div class=\"sodatext");
        if(side_idx == -1) {
            break;
        }
        content = content.substring(side_idx, content.length);
        m[i] = content.substring(22, content.indexOf("<br>"));
        m[i] = m[i].replace(/href="\//g, 'href="http://www.imdb.com/');
        content = content.substring(content.indexOf("<br>"), content.length);
    }
    if (m.length < 1) {
        return;
    }
    return { rating: m, index: index };
}

function extractStorylineInfo(status, state, content, index) {
    if (state !=4) {
        return;
    }
    var storyline_idx = content.indexOf("<h2>Storyline</h2>");
    if(storyline_idx == -1) {
        return;
    }
    var p = content.substring(storyline_idx, content.length);
    var m = p.substring(p.indexOf("<p>")+3, p.indexOf("<em")-1);
    if (m == null) {
        return;
    }
    if (m.indexOf("Add Full Plot") > 0) {
        return { rating: "No storyline available", index: index };;
    }
    //document.body.innerHTML =  "<xmp>" + m + "</xmp>" +  "<br>" + document.body.innerHTML;
    return { rating: m, index: index };
}

function getImdbUrl(mtitle, callback) {
    GM_xmlhttpRequest({
        method: "GET",
        url: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=' + mtitle + '+site:imdb.com',
        onload:function(details) {
            var res = eval('(' + details.responseText + ')');
            url2 = res.responseData.results[0].unescapedUrl;
            callback(url2);
        }
    });
}

function getWikipediaUrl(mtitle, callback) {
    GM_xmlhttpRequest({
        method: "GET",
        url: 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=' + mtitle + '+site:en.wikipedia.org',
        onload:function(details) {
            var res = eval('(' + details.responseText + ')');
            url2 = res.responseData.results[0].unescapedUrl;
            callback(url2);
        }
    });
}


// MAIN ==================================================================================

if ( !window.location.href.match(/www.hulu.com\/watch\/.*/i)) {
    //alert("no show: " + window.location.href);
    exit();
}

// infer movie name from <title>
var title=document.title;
re = new RegExp('[:,.;-]+.*', "g");
var tmp =  title.replace("Hulu - ",'','g');
tmp =  tmp.replace(re,'','g');
var movieNameURI = encodeURIComponent(tmp);
var movieName = tmp;

// create a left-aligned panel to display additional content in
var prepend = '<div id="augmented" style="min-height:100%; z-index:9999999; text-align: left; background: white; position:absolute; left:10px; top:75px; width: 233px; border:2px solid #aaa; padding:5px;">';
var append = ' <div style="display:block; background-color:#face65; text-align:left; font-size:13pt; padding:3px;">&nbsp;<b>Facebook</b></div><div id="facebookdiv"></div></div>';

// create a right-aligned panel to display metadata
var right_append = '<div id="metafloat" style="position:absolute; right:10px; top:75px; float:right; width:245px; z-index:999999; text-align:right"><span id="wikitable"></span><br /></div>';

// attach additional content to original page
document.body.innerHTML = prepend + '<div style="display:block; font-size:14pt; background-color:#ccc;">&nbsp;<b><i>' + movieName + '</i></b></div><div id="storyline" style="padding:10px;"><i>Loading storyline from IMDb...</i><br /><br /></div>' + append + right_append + document.body.innerHTML;

// query imdb via google (take the first search result)
getImdbUrl(movieNameURI, function(url2) {
    var imdblinkspan = document.createElement('span');
    var imdblink = '\
 <div style="display:block; background-color:#face65; text-align:left; font-size:13pt; padding:3px;">&nbsp;<b>Reviews</b></div>\
 <div style="display:block; background-color:#def; text-align:right; padding:3px;"><b>&nbsp;<a target="_blank" href="http://www.rottentomatoes.com/search/movie.php?searchby=movies&page=0&search=' + movieNameURI + '">RottenTomatoes.com</a>&nbsp;</b></div>\
 <div style="padding:5px; padding-left:10px;">\
    <a target="_blank" href="http://www.rottentomatoes.com/search/movie.php?searchby=movies&page=0&search=' + movieNameURI + '">Search <i>' + movieName + '</i> on RottenTomatoes</a><br /><br /> </div>\
  <div style="display:block; background-color:#def; text-align:right; padding:3px;"><b>&nbsp;<a target="_blank" href="' + url2 +'">IMDB</a>&nbsp;</b></div>\
 <div style="padding:5px;">\
   <a target="_blank" href="' + url2 +'"><b><i>' + movieName + '</i> on IMDB:</b></a>\
 </div>';
    
    imdblink += '<div style="padding-left:30px;"><span id="imdb_rating">loading ratings...<br></span></div>';
    imdblinkspan.innerHTML = imdblink;
    document.getElementById('augmented').appendChild(imdblinkspan);

/*    var facebookspan = document.createElement('span');
    facebookspan.innerHTML = '<br /> <div style="display:block; background-color:#face65; text-align:left; font-size:13pt; padding:3px;">&nbsp;<b>Facebook</b></div>' + 
        '<div style="display:block; background-color:#def; text-align:right; padding:3px;"><b>&nbsp;<a target="_blank" href="' + url2 +'trivia">IMDB</a>&nbsp;</b></div>' +
        '<div id="facebookdiv" style="padding:10px;"></div>';

    document.getElementById('augmented').appendChild(facebookspan);
*/
    var triviaspan = document.createElement('span');


    triviaspan.innerHTML = '<br /><div style="display:block; background-color:#face65; text-align:left; font-size:13pt; padding:3px;">&nbsp;<b>Trivia</b></div>' + 
        '<div style="display:block; background-color:#def; text-align:right; padding:3px;"><b>&nbsp;<a target="_blank" href="' + url2 +'trivia">IMDB</a>&nbsp;</b></div>' +
        '<div id="trivia_contents" style="padding:10px;"></div>';
    document.getElementById('augmented').appendChild(triviaspan);

    // if we have a nonnull google search result
    if (findImdbID(url2) != null) {
        getMovieInfo(url2, function(rating) {
            var IMDB_rating_span = document.getElementById('imdb_rating');
            IMDB_rating_span.innerHTML = '<div style="padding-left:10px;">\
                <table border=0 padding=5><tr><td><a target="_blank" href="' + url2 +'">Rating: <b>' + rating.rating + '&nbsp;&nbsp;</b></a></td>' + 
                '<td align=right> <a target="_blank" href="' + url2 +'">\
                   <div style="width: 60px; background: url(http://www.hulu.com/images/rating_empty.gif) 0 0 repeat-x;">\
                     <div style="width:' + rating.rating*10 + '%; height: 12px; background: url(http://www.hulu.com/images/rating_full.gif) 0 0 repeat-x;">\
                     </div>\
                   </div></a>\
                </td></tr></table>\
                 </div></a>';
        });
        getTriviaInfo(url2, function(rating) {
            var IMDB_trivia_span = document.getElementById('trivia_contents');
            var m = rating.rating;
            var m_text = "";
            for(i = 0; i < m.length; i++) {
                m_text += m[i];
            }
            IMDB_trivia_span.innerHTML = m_text +
                '<div style="text-align:right"><a href="' + url2 + 'trivia">[more trivia on IMDb]</a></div>';
        });
        getStorylineInfo(url2, function(rating) {
            var IMDB_storyline_span = document.getElementById('storyline');
            var m = rating.rating;
            IMDB_storyline_span.innerHTML = m.substring(0, 200) + "..." +
                '<div style="text-align:right"><a href="' + url2 + '">[full storyline on IMDb]</a></div><br />';
        });
    }
    // failsafe
    else {
	imdblinkspan.innerHTML = "<br/> IMDB: <a target=\"_blank\" href=\"http://www.imdb.com/find?s=tt&q="+movieNameURI+"\">Not Found</a><br>";
    }

    // also append amazon 
    imdblinkspan.innerHTML += '<br /><br /><div style="display:block; background-color:#face65; text-align:left; font-size:13pt; padding:3px;">&nbsp;<b>Shopping</b></div>\
 <div style="display:block; background-color:#def; text-align:right; padding:3px;"><b>&nbsp;\
   <a target="_blank" href="http://www.amazon.com/gp/search?ie=UTF8&keywords=' + movieNameURI + '&tag=imdb-title-20&index=dvd">Amazon.com</a></b>&nbsp;</div>\
   <div style="padding:10px;"><a target="_blank" href="http://www.amazon.com/gp/search?ie=UTF8&keywords=' + movieNameURI + '&tag=imdb-title-20&index=dvd">Buy <i>' + movieName + '</i> on Amazon</a></div>';

});

getWikipediaUrl(movieNameURI, function(url2) {
    getWikipediaInfo(url2, function(rating) {
        var wikitable = document.getElementById('wikitable');
        wikitable.innerHTML += '\
            <div style="background-color:#fff; padding:5px;border:2px solid #aaa;">' +

            '<div style="display:block; background-color:#face65; text-align:left; font-size:13pt; padding:3px;">&nbsp;<b>Overview</b></div>' +
            '<div style="display:block; background-color:#def; text-align:right; padding:3px;"><b>&nbsp;<a target="_blank" href="' + url2 +'">wikipedia.org</a>&nbsp;</b></div>' +
                '<br />\
                <div id="toggle_wikipedia">' + rating.rating + "</div>\
            </div>";
    });
});



function onFBLogin(){
  var url = 'http://ahulubeta.appspot.com/facebook?mode=name&uid=' + userid;
GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	onload: function(details) {
    document.getElementById('welcome').innerHTML = 'Welcome to ahulu, ' + details.responseText;
document.getElementById('like').innerHTML += '<a id="alike" href="#">Like</a> ' + movieName + ' on Facebook';
  document.getElementById('share').innerHTML += '<a id="ashare" href="#">Share</a> video on status';

var elmLink = document.getElementById('ashare');
elmLink.addEventListener("click", wanttoshare, true);

var elmLink = document.getElementById('alike');
elmLink.addEventListener("click", like, true);

	}
  });
}

function like(){
  var url = 'http://ahulubeta.appspot.com/facebookpost?media=' + movieName;
  GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	onload: function(details) {
       var fburl = details.responseText;
       window.open(fburl);
    }
  });
  return false;
}

function wanttoshare(){
  document.getElementById('share').innerHTML = '<input type="textarea" id="post" rows="4" cols="155"/><input id="buttonshare" type="button" value="POST"/>';
var elmLink = document.getElementById('buttonshare');
elmLink.addEventListener("click", share, true);
return false;
}


function share(){
  var body = document.getElementById('post').value;
 var url = 'http://ahulubeta.appspot.com/facebookpost?status=' + body + '&uid=' + userid + '&link=' + window.location;
GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	onload: function(details) {
    document.getElementById('share').innerHTML = 'Post shared! <a id="ashare" href="#" >Share more?</a>';

var elmLink = document.getElementById('ashare');
elmLink.addEventListener("click", wanttoshare, true);
	}
  });
  return false;
}

function fbinit(){
  var url = 'http://ahulubeta.appspot.com/facebookpost?media=' + movieName;
GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	onload: function(details) {
	  var i = 1;
	}
  });
}

function getCookie(Name){ //get cookie value
var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return ""
}

function setCookie(name, value, days){ //set cookie value
var expireDate = new Date()
var expstring=expireDate.setDate(expireDate.getDate()+parseInt(days))
document.cookie = name+"="+value+"; expires="+expireDate.toGMTString()+"; path=/";
}

var userid = null;
var urltovisit = window.location;


function init() {
if(getCookie("userid") == ""){
  var url = 'http://ahulubeta.appspot.com/facebook?mode=uid';
  GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	onload: function(details) {
       userid = details.responseText;
       setCookie("userid", userid, 30);
       part2();
	}
  });
} else {
  userid = getCookie("userid");
//  window.location('http://ahulubeta.appspot.com/facebook?uid=' + userid);
  part2();
}
}

function part2(){
urltovisit = 'http://ahulubeta.appspot.com/facebook?uid=' + userid + '&redirecturl=' + window.location;
document.getElementById("facebookdiv").innerHTML += 
'<div id="welcome"><a href=' + urltovisit +'>Login</a> to fb!</div><div id="like"></div><div id="share"></div>';

var url = 'http://ahulubeta.appspot.com/facebook?mode=logincheck&uid=' + userid;

GM_xmlhttpRequest({
	method: 'GET',
	url: url,
	onload: function(details) {
       var resp = details.responseText;
       if(resp == 'yes'){
		onFBLogin();
 	  }
	}
});

}

function fblogin(){
  var redirecturl = window.location;
  window.location('http://ahulubeta.appspot.com/facebook?uid=' + userid + '&redirecturl=' + window.location);
}

document.onload = init();


